package ar.com.aterrizar.aerolineas;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.uqbar.commons.model.UserException;
import com.oceanic.AerolineaOceanic;
import com.oceanic.AsientoDTO;
import ar.com.aterrizar.asientos.Asiento;
import ar.com.aterrizar.asientos.AsientoOceanic;
import ar.com.aterrizar.entidades.Cliente;
import ar.com.aterrizar.entidades.TipoDeClaseAsiento;
import ar.com.aterrizar.entidades.TipoDeUbicacionAsiento;

public class AeroOceanic implements Aerolinea {

	private String aerolinea = "oceanic";
	private final AerolineaOceanic oceanic;
	private Float porcentaje = (float) 1.0;
	private Collection<Asiento> asientos;
	private Collection<Asiento> asientosComprados = new ArrayList<Asiento>();
	private static AeroOceanic INSTANCE;


	public static AeroOceanic getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new AeroOceanic();
		}

		return INSTANCE ;
	}

	protected AeroOceanic() {
		this.oceanic = AerolineaOceanic.getInstance();
	}

	/**
	 * Solo para test
	 * @param oceanicMock
	 */
	public AeroOceanic(AerolineaOceanic oceanicMock){
		this.oceanic = oceanicMock;
	}


	public Boolean estaReservado(Asiento asiento) {
		return oceanic.estaReservado(asiento.getCodVuelo(), asiento.getNumAsiento());
	}


	public void reservar(Asiento asiento, Cliente cliente) {

		Boolean resultadoDeLaReserva = oceanic.reservar(cliente.getDni()
				.toString(), asiento.getCodVuelo(), asiento
				.getNumAsiento());

		if (!(resultadoDeLaReserva)) {
			throw new UserException("Ha ocurrido un error en su reserva < La operación solicitada no puede realizarse sobre el asiento, debido a un conflicto con su estado. > intente nuevamente");
		}

	}


	public Collection<Asiento> getAsientos() {
		return asientos = null;
	}


	public void comprar(Asiento asiento, Cliente cliente) {

		Boolean resultadoDeLaCompra = oceanic.comprarSiHayDisponibilidad(
				cliente.getDni().toString(), asiento.getCodVuelo(),
				asiento.getNumAsiento());

		if (resultadoDeLaCompra) {
			this.asientosComprados.add(asiento);
		}else {
			throw new UserException("Ha ocurrido un error en su compra < La operación solicitada no puede realizarse sobre el asiento, debido a un conflicto con su estado. > intente nuevamente");
		}

	}


	public String getAerolinea() {
		return this.aerolinea;
	}


	public Float getPorcentaje() {
		return this.porcentaje;
	}


	public Collection<Asiento> getAsiento(String origen, String fechaSalida) {

		asientos = new ArrayList<Asiento>();

		List<AsientoDTO> asientosOceanic = oceanic.asientosDisponiblesParaOrigen(origen, fechaSalida);

		if (asientosOceanic == null) {
			return asientos = null;
		}
		return asientos = formatearLista(asientosOceanic);
	}


	public Collection<Asiento> getAsiento(String origen, String fechaSalida,
			String destino) {

		asientos = new ArrayList<Asiento>();

		List<AsientoDTO> asientosOceanic = oceanic
				.asientosDisponiblesParaOrigenYDestino(origen, destino,
						fechaSalida);

		if (asientosOceanic == null) {
			return asientos = null;
		}
		return asientos = formatearLista(asientosOceanic);
	}


	public Collection<Asiento> getAsiento(String origen, String fechaSalida,
			String horaSalida, String destino, String fechaLlegada,
			String horaLlegada) {

		return asientos = null;
	}


	public Collection<Asiento> vuelosComprados() {
		return this.asientosComprados;
	}


	private Collection<Asiento> formatearLista(List<AsientoDTO> listaSinFormato) {

		Collection<Asiento> listaDeAsientos = new ArrayList<Asiento>();

		for (AsientoDTO asiento : listaSinFormato) {

			String fechaYHoraLlegada = asiento.getFechaDeLlegada() + " " + asiento.getHoraDeLlegada();
			String fechaYHoraSalida = asiento.getFechaDeSalida() + " " + asiento.getHoraDeSalida();

			AsientoOceanic asientoOceanic = new AsientoOceanic(
					asiento.getCodigoDeVuelo(),
					asiento.getNumeroDeAsiento(),
					fechaYHoraLlegada,
					fechaYHoraSalida,
					asiento.getOrigen(), asiento.getDestino(),
					new Float(asiento.getPrecio().floatValue()),
					formatClase(asiento.getClase()), formatUbicacion(asiento
							.getUbicacion()), asiento.getReservado());

			listaDeAsientos.add(asientoOceanic);

		}

		return listaDeAsientos;
	}


	private TipoDeUbicacionAsiento formatUbicacion(String ubicacion) {
		if (ubicacion == "Ventana") {
			return TipoDeUbicacionAsiento.VENTANA;
		}
		if (ubicacion == "Centro") {
			return TipoDeUbicacionAsiento.CENTRO;
		}
		return TipoDeUbicacionAsiento.PASILLO;
	}


	private TipoDeClaseAsiento formatClase(String clase) {
		if (clase == "Primera") {
			return TipoDeClaseAsiento.PRIMERACLASE;
		}
		if (clase == "Turista") {
			return TipoDeClaseAsiento.TURISTA;
		}
		return TipoDeClaseAsiento.EJECUTIVA;
	}

	public int vuelosComprados(String codigoDeVuelo){
		int cant=0;
		for(Asiento asiento:this.vuelosComprados()){
			if(asiento.getCodVuelo()==codigoDeVuelo){
				cant++;
			}
		}
		return cant;
	}

}
